package pub.gll.plugin.asm.annotation;

import com.android.build.api.transform.Status;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;

import pub.gll.plugin.util.CheckClass;


public class ArchCollectClassVisitor extends ClassVisitor {
    private Status status;
    private boolean isArchOriginalClass = false;
    private String className;

    public ArchCollectClassVisitor(int api, ClassVisitor cv, Status status) {
        super(api, cv);
        this.status = status;
    }


    @Override
    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
        if (!isArchOriginalClass) {//如果没有找到是否含有指定注解，则接着获取，否则只要找到一个就不需要获取了
            return new ArchCollectFieldVisitor(Opcodes.ASM7, super.visitField(access, name, desc, signature, value));
        } else {
            return super.visitField(access, name, desc, signature, value);
        }
    }


    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces);
        className = name;

    }

    @Override
    public void visitEnd() {
        super.visitEnd();
        if (status == Status.ADDED) {
            added(className);
        } else if (status == Status.CHANGED) {
            changed(className);
        }
    }

    private void added(String className) {
        if (className.endsWith(CollectArchBindingDataContainer.ARCH_END_POSIX)) {//如果是arch_binding 结尾的,直接注册
            CollectArchBindingDataContainer.registerDataClass(className.substring(0, className.length() - CollectArchBindingDataContainer.ARCH_END_POSIX.length()), className);
        }
    }

    private void changed(String className) {//如果是change，且是原始类并且包含指定注解，则说明之前一定有
        if (className.endsWith(CollectArchBindingDataContainer.ARCH_END_POSIX)) {//如果是arch_binding 结尾的,直接注册
            CollectArchBindingDataContainer.registerDataClass(className.substring(0, className.length() - CollectArchBindingDataContainer.ARCH_END_POSIX.length()), className);
        } else if (CheckClass.isSubClassWithRulesAndIsNotSelf(className) && isArchOriginalClass) {
            CollectArchBindingDataContainer.registerDataClass(className, className + CollectArchBindingDataContainer.ARCH_END_POSIX);
        }
    }


    class ArchCollectFieldVisitor extends FieldVisitor {
        public ArchCollectFieldVisitor(int api, FieldVisitor fv) {
            super(api, fv);
        }

        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            if (CheckClass.isRulesAnnotation(desc)) {
                isArchOriginalClass = true;
            }
            return super.visitAnnotation(desc, visible);

        }
    }

}
